package cn.com.captureNetPacket.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioFormat.Encoding;

import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import cn.com.captureNetPacket.record.WavFileInfo;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class WavFileUtil {
    private static ObjectMapper objectMapper = new ObjectMapper();
    private static final int HEAD_LENGTH = 12;

    private static final int FORMAT_LENGTH = 24;

    private static boolean isWav(byte[] head) throws UnsupportedEncodingException {
        return ("RIFF".equals(new String(head, 0, 4, "ISO_8859_1")) &&
                "WAVE".equals(new String(head, 8, 4, "ISO_8859_1")));
    }

    private static void fileTooSmall(byte[] file) throws IOException {
        if (file.length < HEAD_LENGTH + FORMAT_LENGTH) {
            log.warn("file is too small, size if {}.", file.length);
            throw new IOException("file is too small, size if "+file.length);
        }
    }

    private static int headSize() {
        return HEAD_LENGTH + FORMAT_LENGTH;
    }
    
    
    
    /**
     * 
    	* <strong>Title: <strong>
    	* <p>Description: 根据路径和文件名获取文件的头信息<p>
    	* <p>Company: </p> 
    	*<strong>Copyright:</strong> Copyright (c) 2019
    	* @version: 1.0
    	* @author  ASUS:augustWei
    	* @date  2020 上午2:41:27
    	* @param fileName
     * @throws JsonProcessingException 
     * @throws FileNotFoundException 
     */
    public static WavFileInfo getWaveFileInfo(final String fileName) throws JsonProcessingException, FileNotFoundException {
    	if(fileName==null)return null;
    	  WavFileInfo wavFileInfo=null;
    	  File file = new File(fileName);
    	  if(!file.exists())
    		  {
    		  log.error("WavFileUtil getWaveFileInfo 文件 {} 不存在。",fileName);
    		  return null;
    		  }
		  if(file.length()<1){
			  log.error("WavFileUtil getWaveFileInfo 文件 {} 大小为零。",fileName);
			  return null;
		  }
    	  FileChannel fileChannel = new RandomAccessFile(file,"r").getChannel();
    	  ByteBuffer byteBuffer = ByteBuffer.allocate(100);
    	  byte[] head = null ;
    	try {
			fileChannel.read(byteBuffer);
			head=byteBuffer.array();
			 byteBuffer.flip();
	            byteBuffer.get(head);
	            byteBuffer.clear();

			  fileTooSmall(head);
//			  byte[] head = copyOfRange(fileStream, 0, HEAD_LENGTH);
			  if(!isWav(head)) {
				  log.warn("checkWaveFile is not wave file path:{} file:{} IOException",fileName);
				  return null;
			  }
			    wavFileInfo=new WavFileInfo();
			  // 设置头信息
			  wavFileInfo.setHeadRiff(head);
			  // 获取format 的长度，16没有fact区域，18有，不同的处理。 headFormat和headData不同的处理
			  wavFileInfo.setHead_chunkSize( ByteBuffer.wrap(copyOfRange(head, 16, 20)).order(ByteOrder.LITTLE_ENDIAN).getShort());
			  if(wavFileInfo.getHead_chunkSize()==16) {
				  wavFileInfo.setHeadFormat(copyOfRange(head, 12, 36));
				  wavFileInfo.setHeadData(copyOfRange(head, 36, 44));
				  wavFileInfo.setHead(copyOfRange(head, 0, 44));
			  }else {
				  wavFileInfo.setHeadFormat(copyOfRange(head, 12, 50));
				  wavFileInfo.setFact_data(copyOfRange(head, 46, 50));
				  wavFileInfo.setHeadData(copyOfRange(head, 50, 58));
				  wavFileInfo.setHead(copyOfRange(head, 0, 58));
			  }
			  //设置文件RIFF文件块数据大小
			  wavFileInfo.setHead_chunkSize(ByteBuffer.wrap(copyOfRange(head, 4, 8))
	                    .order(ByteOrder.LITTLE_ENDIAN)
	                    .getInt());
		} catch (IOException e) {
			 log.error("checkWaveFile fail path:{} file:{} IOException",fileName,e);
		}
    	finally {
    		try {
				fileChannel.close();
			} catch (IOException e) {
				 log.error("checkWaveFile close  fail path:{} file:{} IOException",fileName,e);
			}
		}
    	log.info(" wavFileInfo: {}",objectMapper.writeValueAsString(wavFileInfo));
    	return wavFileInfo;
    }
    
    
    /**
     * 
    	* <strong>Title: <strong>
    	* <p>Description: 根据WavFileInfo 信息生成head信息<p>
    	* <p>Company: </p> 
    	*<strong>Copyright:</strong> Copyright (c) 2019
    	* @version: 1.0
    	* @author  ASUS:augustWei
    	* @date  2020 上午2:46:50
    	* @param wavFileInfo
    	* @return
     * @throws UnsupportedEncodingException 
     */
    public static WavFileInfo createWavFileHead(WavFileInfo wavFileInfo) throws UnsupportedEncodingException {
    	ByteBuffer head = null;
    	
    	//RIFF  12
    	 ByteBuffer head_chunkID =  ByteBuffer.allocate(4).put("RIFF".getBytes("ISO_8859_1")); 
    	 ByteBuffer head_chunkSize = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(wavFileInfo.getHead_chunkSize());
    	 ByteBuffer head_formatType =  ByteBuffer.allocate(4).put("WAVE".getBytes("ISO_8859_1"));  
    	 
    	 // format
    	 ByteBuffer format_chunkID=  ByteBuffer.allocate(4).put("fmt ".getBytes("ISO_8859_1")); 
    	 ByteBuffer format_chunkSize = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(wavFileInfo.getFormat_chunkSize());
    	 
    	 ByteBuffer format_audioFormat = ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort(wavFileInfo.getFormat_audioFormat());
    	 ByteBuffer format_channel = ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort(wavFileInfo.getFormat_channel());
    	 
    	 ByteBuffer format_sampleRate = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(wavFileInfo.getFormat_sampleRate());
    	 ByteBuffer format_byteRate = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(wavFileInfo.getFormat_byteRate());
    	 
    	 ByteBuffer format_blockAlign = ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort(wavFileInfo.getFormat_blockAlign());
    	 ByteBuffer format_bitsPerSample = ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort(wavFileInfo.getFormat_bitsPerSample());
    	 
    	 // data
    	 ByteBuffer data_chunk_id= ByteBuffer.allocate(4).put("data".getBytes("ISO_8859_1"));
    	 ByteBuffer data_size = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(wavFileInfo.getData_size());
    	 
    	 
    	 		if(wavFileInfo.getFormat_chunkSize()==18) {
    	 			 head = ByteBuffer.allocate(58);
    	 			 
    	 			}
    	 		else {
    	 			 head = ByteBuffer.allocate(44);
    	 		}
    	 		//RIFF
    	 head.put(head_chunkID.array());
    	 head.put(head_chunkSize.array());
    	 head.put(head_formatType.array());
    	 // format
    	 head.put(format_chunkID.array());
    	 head.put(format_chunkSize.array());
    	 
    	 head.put(format_audioFormat.array());
    	 head.put(format_channel.array());
    	 
    	 head.put(format_sampleRate.array());
    	 head.put(format_byteRate.array());
    	 
    	 head.put(format_blockAlign.array());
    	 head.put(format_bitsPerSample.array());
    	 // format 添加附加信息
    	 if(wavFileInfo.getFormat_chunkSize()==18) {
    		 // 添加2个字节的补位
    		 ByteBuffer format_factEnd = ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort(wavFileInfo.getFormat_factEnd());
    		 ByteBuffer format_fact= ByteBuffer.allocate(4).put("fact".getBytes("ISO_8859_1"));
    		 ByteBuffer fact_dataSize = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(wavFileInfo.getFact_dataSize());
    		 head.put(format_factEnd.array());
    		 head.put(format_fact.array());
    		 head.put(fact_dataSize.array());
    		 head.put(wavFileInfo.getFact_data());
 			}
    	 // data
    	 head.put(data_chunk_id.array());
    	 head.put(data_size.array());
    	 
    	 //设置head
    	 wavFileInfo.setHead(head.array());
    	return wavFileInfo;
    }
    
    
    
    
    /**
     * resolve wav file head.
     * ChunkID,ChunkSize,Format, everyone 4 bytes.
     * @throws IOException 
     */
    public static int fileSize(byte[] file) throws IOException {
        fileTooSmall(file);

        byte[] head = copyOfRange(file, 0, HEAD_LENGTH);

        if (isWav(head)) {
            return ByteBuffer.wrap(copyOfRange(head, 4, 8))
                    .order(ByteOrder.LITTLE_ENDIAN)
                    .getInt() + 8;
        } else {
            log.warn("file format error: expected {}, actual {}.",
                    "[82, 73, 70, 70, *, *, *, *, 87, 65, 86, 69]",
                    head);
            return 0;
        }
    }

    public static AudioFormat fileFormat(byte[] file) throws IOException {
        fileTooSmall(file);

        byte[] head = copyOfRange(file, 0, HEAD_LENGTH);

        if (isWav(head)) {
            byte[] format = copyOfRange(file, 12, HEAD_LENGTH + FORMAT_LENGTH);
            String chuckID = new String(format, 0, 4, "ISO_8859_1");
            int chunkSize = ByteBuffer.wrap(copyOfRange(format, 4, 8))
                    .order(ByteOrder.LITTLE_ENDIAN).getInt();
            int audioFmt = ByteBuffer.wrap(copyOfRange(format, 8, 10))
                    .order(ByteOrder.LITTLE_ENDIAN).getShort();
            int channels = ByteBuffer.wrap(copyOfRange(format, 10, 12))
                    .order(ByteOrder.LITTLE_ENDIAN).getShort();
            int sampleRate = ByteBuffer.wrap(copyOfRange(format, 12, 16))
                    .order(ByteOrder.LITTLE_ENDIAN).getInt();
            int byteRate = ByteBuffer.wrap(copyOfRange(format, 16, 20))
                    .order(ByteOrder.LITTLE_ENDIAN).getInt();
            int frameSize = ByteBuffer.wrap(copyOfRange(format, 20, 22))
                    .order(ByteOrder.LITTLE_ENDIAN).getShort();
            int sampleSizeInBits = ByteBuffer.wrap(copyOfRange(format, 22, 24))
                    .order(ByteOrder.LITTLE_ENDIAN).getShort();

            return new AudioFormat(Encoding.PCM_SIGNED, sampleRate,
                    sampleSizeInBits, channels, frameSize, sampleRate, false);
        } else {
            log.warn("file is not a wav.");
        }
		return null;
    }
  
 
    
    /**
     * 
    	* <strong>Title: <strong>
    	* <p>Description: 任意时刻追加数据到文件<p>
    	* <p>Company: </p> 
    	*<strong>Copyright:</strong> Copyright (c) 2019
    	* @version: 1.0
    	* @author  ASUS:augustWei
    	* @date  2020 下午11:57:45
    	* @param data
    	* @param path
    	* @throws IOException
     */
    public static void appendToFile(final byte[] data ,int writeLen, final String path) throws IOException {
    	try (RandomAccessFile randomAccessFile = new RandomAccessFile(path, "rw")) {
    	 randomAccessFile.seek(randomAccessFile.length());
//    		file.write(data);
    		randomAccessFile.write(data, 0, writeLen);
//    		randomAccessFile.write(WavFileUtil.convertG711ToPcm(data, null), 0, writeLen);
    		randomAccessFile.close();
    	} catch (Exception e) {
    		log.error("Exception",e);
    	}
    }
    
   /**
    * 
   	* <strong>Title: <strong>
   	* <p>Description: 根据路径合成文件<p>
   	* <p>Company: </p> 
   	*<strong>Copyright:</strong> Copyright (c) 2019
   	* @version: 1.0
   	* @author  ASUS:augustWei
   	* @date  2020 上午12:46:02
   	* @param wavFileInfo 需要创建的音乐文件的头信息
   	* @param leftFileName  左声道文件
   	* @param rightFileName 右声道文件
   	* @param newFile 新生成的文件
   	* @return
   	* @throws UnsupportedEncodingException
    */
    
    public static int mergeWave(WavFileInfo wavFileInfo,final String leftFileName, final String rightFileName, final String newFile) throws UnsupportedEncodingException {
   	 try {
   		 log.info("merge   wavFileInfo:{} leftFile:{} rightFile:{} newFile:{}",wavFileInfo,leftFileName,rightFileName,newFile);
   		byte[] leftData=null,rightData=null;int leftOffset=0,rightOffset=0;
   		WavFileInfo leftWavFileInfo=getWaveFileInfo(leftFileName);
   		WavFileInfo rightWavFileInfo=getWaveFileInfo(rightFileName);
   				if(leftWavFileInfo!=null) {
//					    获取录音文件语音数据块开始的位置。
					leftOffset = leftWavFileInfo.getHead().length;
				}

//根据位移，读取左声道主数据
		 try {
			 leftData = readDataFromFile(leftOffset, leftFileName);
		 }catch (Exception e) {
			 log.warn("mergeWave left 未获取到：leftFileName {}  , 新文件: {} IOException",rightFileName,newFile,e);
		 }

   				if(rightWavFileInfo!=null) {
					//					    获取录音文件语音数据块开始的位置。
   					rightOffset=rightWavFileInfo.getHead().length;
   					}

		 //根据位移，读取右声道数据
		 try {
			 rightData=readDataFromFile(rightOffset,rightFileName);
		 }catch (Exception e) {
			 log.warn("mergeWave right 未获取到：rightFileName {}  , 新文件: {} IOException",rightFileName,newFile,e);
		 }
				   if(leftData!=null ) {
					   mergeWaveAsFile(wavFileInfo, leftData, rightData, newFile);
				   }else if(rightData!=null){
					   log.warn("mergeWave left 未获取到数据，只能将right作为主录音：rightFileName {}  , 新文件: {} ",rightFileName,newFile);
					   mergeWaveAsFile(wavFileInfo, rightData,leftData, newFile);

				   }
        } catch (IOException e) {
           log.error("mergeWave wavFileInfo:{} leftFile:{} rightFile:{} newFile:{} IOException",wavFileInfo,leftFileName,rightFileName,newFile,e);
           return -1;
        }

   	return 1;
   }
    
    
    private static byte[] readDataFromFile(final int offset, final String path) {
    	if(path==null)
    		return null;
		if(Files.exists(Paths.get(path))){
			log.info("读取的文件不存在，readDataFromFile offset: {}, path: {} readSize:{}",offset,path);
		}
    	 byte[] byteBuffer=null;
    	   try (RandomAccessFile randomAccessFile = new RandomAccessFile(path, "r")) {
    		   byteBuffer=new byte[(int) (randomAccessFile.length()-offset)];
    		    
    		   randomAccessFile.readFully(byteBuffer);
    		   randomAccessFile.close();
           } catch (IOException e) {
           	log.warn("IOException 读取错误：{}",path);
           	return null;
           }
    	   log.info("readDataFromFile offset: {}, path: {} readSize:{}",offset,path,byteBuffer.length);
		return byteBuffer;
    }
    
    
    /**
     * 
    	* <strong>Title: <strong>
    	* <p>Description: 根据头信息，合并纯的2条数据数据，并直接生成文件.与mergeWaveData方法的区别是循环过程中已经在写入文件了。<p>
    	* <p>Company: </p> 
    	*<strong>Copyright:</strong> Copyright (c) 2019
    	* @version: 1.0
    	* @author  ASUS:augustWei
    	* @date  2020 上午12:21:05
    	* @param wavFileInfo 文件信息
    	* @param left 左声道
    	* @param right 右声道
    	* @param path 存放的路径
    	* @throws IOException
     */
    private static void mergeWaveAsFile(WavFileInfo wavFileInfo ,final byte[] left, final byte[] right, final String path) throws IOException {
    	int leftLength=0,rightLength=0;
    	if(left!=null) {
    		leftLength=left.length;
    	}
    	if(right!=null) {
    		rightLength=right.length;
    	}
        try (RandomAccessFile randomAccessFile = new RandomAccessFile(path, "rw")) {
        	int max =0;
        	max= Math.max(leftLength, rightLength);
        	if(right!=null) {
        		wavFileInfo.setData_size(max*2);
        	}
        	else {
        		wavFileInfo.setData_size(max);
        		
        	}
        	wavFileInfo.reInitValue();
        	createWavFileHead(wavFileInfo);
            randomAccessFile.write(wavFileInfo.getHead());
            
//            for (int i = 0; i < max; i += 2) {    // 16 bit,具体看使用的占几位，也就是byte， 对应读取readSamplingUnit_bak，里面占2个位
//            for (int i = 0; i < max; i += 1) {    // alaw 8 bit，可以用这个。其他的要测试。
            int byteCount=1;
            byteCount=wavFileInfo.getFormat_bitsPerSample()/8;   // 8bit =1byte
            if(right!=null) {
				            for (int i = 0; i < max; i += byteCount) {
				                randomAccessFile.write(readSamplingUnit(left, i,byteCount));
				                randomAccessFile.write(readSamplingUnit(right, i,byteCount));
				            }
            
            }
            else {
			            	 for (int i = 0; i < max; i += byteCount) {
			                     randomAccessFile.write(readSamplingUnit(left, i,byteCount));
			                 }
            }
            randomAccessFile.close();
            log.info("mergeWave   write file complete wavFileInfo : {}",wavFileInfo);
        } catch (IOException e) {
        	log.warn("IOException",e);
        }
    }
    
    
    /**
     * 
    	* <strong>Title: <strong>
    	* <p>Description: 根据头信息，合并纯的2条数据数据，返回生成文件的数组信息。适合小文件合并，占用内存少的情况。<p>
    	* <p>Company: </p> 
    	*<strong>Copyright:</strong> Copyright (c) 2019
    	* @version: 1.0
    	* @author  ASUS:augustWei
    	* @date  2020 下午7:23:52
    	* @param wavFileInfo
    	* @param left 左声道数据
    	* @param right 右声道数组
    	* @param path 不为空则生成文件。
    	* @throws IOException
     */
    public static byte [] mergeWaveData(WavFileInfo wavFileInfo ,final byte[] left, final byte[] right, final String path)  {
    	int leftLength=0,rightLength=0;
    	if(left!=null) {
    		leftLength=left.length;
    	}
    	if(right!=null) {
    		rightLength=right.length;
    	}
    	byte [] voiceDate= null;
    	 int copyPos=0;
    	try   {
    		int max =0;
        	max= Math.max(leftLength, rightLength);
        	if(right!=null) {
        		wavFileInfo.setData_size(max*2);
        	}
        	else {
        		wavFileInfo.setData_size(max);
        		
        	}
    		wavFileInfo.reInitValue();
    		createWavFileHead(wavFileInfo);
    		voiceDate=new byte[wavFileInfo.getHead().length+max*2];
    		System.arraycopy(wavFileInfo.getHead(),0,voiceDate,0,wavFileInfo.getHead().length);
    		copyPos=wavFileInfo.getHead().length;
    		
    		
//            for (int i = 0; i < max; i += 2) {    // 16 bit,具体看使用的占几位，也就是byte， 对应读取readSamplingUnit_bak，里面占2个位
//            for (int i = 0; i < max; i += 1) {    // alaw 8 bit，可以用这个。其他的要测试。
    		int byteCount=1;
    		byteCount=wavFileInfo.getFormat_bitsPerSample()/8;   // 8bit =1byte
    		 if(right!=null) {
    		for (int i = 0; i < max; i += byteCount) {
    			System.arraycopy(readSamplingUnit(left, i,byteCount),0,voiceDate,copyPos,byteCount);
    			copyPos+= byteCount;
    			System.arraycopy(readSamplingUnit(right, i,byteCount),0,voiceDate,copyPos,byteCount);
    			copyPos+= byteCount;
    		}
    		 }
    		 else {
    	    		for (int i = 0; i < max; i += byteCount) {
    	    			System.arraycopy(readSamplingUnit(left, i,byteCount),0,voiceDate,copyPos,byteCount);
    	    			copyPos+= byteCount;
    	    		}
    		 }
    		log.info("mergeWaveData 生成wav文件数据完成。  complete wavFileInfo   : {}",wavFileInfo);
    	} catch (Exception e) {
    		log.warn("mergeWaveData Exception",e);
    	}
    	
    	
    	if(path!=null) {
		        try (RandomAccessFile randomAccessFile = new RandomAccessFile(path, "rw")) {
		            randomAccessFile.write(voiceDate);
		            randomAccessFile.close();
		            log.info("mergeWave   write file complete path : {},wavFileInfo: {}",path,wavFileInfo);
		        } catch (IOException e) {
		        	log.warn("IOException",e);
		        }
    	}
    	return voiceDate;
    }
    
    
    /**
     * 
    	* <strong>Title: <strong>
    	* <p>Description: 获取采样单位<p>
    	* <p>Company: </p> 
    	*<strong>Copyright:</strong> Copyright (c) 2019
    	* @version: 1.0
    	* @author  ASUS:augustWei
    	* @date  2020 上午12:30:50
    	* @param content
    	* @param offset
    	* @return
    	* @throws UnsupportedEncodingException
     */
  
    private static byte[] readSamplingUnit(final byte[] content, int offset,int byteCount) throws UnsupportedEncodingException {
    	// 补位的占位符
//    	String sizeOfSeat="\0";
//    	for(int i=0;i<byteCount;i++) {
//    		sizeOfSeat=sizeOfSeat+"\0";
//    	}
    	
    	if (content!=null && content.length > offset) {
    		return copyOfRange(content, offset, offset+byteCount);
    	} else {
    		// 这样写性能好点，每次都循环加 \0,性能不好。只有1,2,3三个值
    		if(byteCount==1) {
    			return "\0".getBytes("ISO_8859_1");
    		}else if(byteCount==2){
    			return "\0\0".getBytes("ISO_8859_1");
    		}
    		else return "\0\0\0".getBytes("ISO_8859_1");
    	}
    }
    private static byte[] readSamplingUnit_bak(final byte[] content, int offset) throws UnsupportedEncodingException {
    	if (content.length > offset) {
    		return copyOfRange(content, offset, offset + 2);
    	} else {
    		return "\0\0".getBytes("ISO_8859_1");
    	}
    }
    
    
    
    
    
    
    private static byte[] read(final byte[] content, int offset) throws UnsupportedEncodingException {
    	if (content.length > offset) {
    		return copyOfRange(content, offset, offset + 2);
    	} else {
    		return "\0\0".getBytes("ISO_8859_1");
    	}
    }
    public static byte[] copyOfRange(final byte[] content, int srcPos,int end) {
    	byte[] targetArr  = new byte[end-srcPos];
    	// 从开始位置复制到新的数组中
    	System.arraycopy(content, srcPos, targetArr, 0, targetArr.length);
    	return targetArr;
    }

    private static int mergeSizeField(int left, int right) {
        int max = Math.max(left - 8, right - 8);
        return max * 2;
    }

    private static int mergeDataSize(int left, int right) {
        int max = Math.max(left - headSize() - 8, right - headSize() - 8);
        return max * 2;
    }

    private static byte[] mergeHead(final byte[] left, final int mergeSize) throws IOException {
        AudioFormat format = fileFormat(left);
    	log.info("--------AudioFormat----------");
		log.info("encoding " + format.getEncoding());
		log.info("channels " + format.getChannels());
		log.info("sampleRate " + format.getSampleRate());
		log.info("frameRate " + format.getFrameRate());
		log.info("properties " + format.properties());
		log.info("sampleSizeInBits " + format.getSampleSizeInBits());
		log.info("frameSize " + format.getFrameSize());
		log.info("--------------AudioInputStream-------");
        ByteBuffer size = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(mergeSize);

        ByteBuffer channels = ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort((short) 2);
        ByteBuffer sampleRate = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN)
                .putInt((int) format.getSampleRate());
        ByteBuffer byteRate = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN)
                .putInt((int) format.getSampleRate() * 2 * format.getSampleSizeInBits() / 8);
        ByteBuffer blockAlign = ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN)
                .putShort((short) (2 * format.getSampleSizeInBits() / 8));
        ByteBuffer bitsPerSample = ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN)
                .putShort((short) format.getSampleSizeInBits());

        
        WavFileInfo wavFileInfo=new WavFileInfo((short)6, (short)2, (int)format.getSampleRate(), (short)format.getSampleSizeInBits(), mergeSize);
//        WavFileInfo wavFileInfo=new WavFileInfo((short)6, (short)2, (int)format.getSampleRate(), (short)format.getSampleSizeInBits(), mergeSize,(short)1,null);
        createWavFileHead(wavFileInfo);
        log.info("mergeHead---------------->>>>{}",wavFileInfo);
        
        return wavFileInfo.getHead();
//        ByteBuffer head = ByteBuffer.allocate(headSize());
//        head.put(left, 0, 4);
//
//        head.put(size.array());
//        head.put(left, 8, 14);
//
//        head.put(channels.array());
//        head.put(sampleRate.array());
//        head.put(byteRate.array());
//        head.put(blockAlign.array());
//        head.put(bitsPerSample.array());
//        return head.array();
    }

    private static byte[] dataChunkHead(final int length) throws UnsupportedEncodingException {
        ByteBuffer head = ByteBuffer.allocate(8);
        head.put("data".getBytes("ISO_8859_1"));
        ByteBuffer size = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(length);
        head.put(size.array());
        return head.array();
    }
    
    
    /**
     *  g711 a 转pcm
     * @param g711Buffer
     * @param pcmBuffer
     * @return
     */
    public static byte[] convertG711ToPcm(byte[] g711Buffer, byte[] pcmBuffer)
	{
		if (pcmBuffer == null)
		{
			pcmBuffer = new byte[g711Buffer.length*2];
		}
		for (int i=0; i<g711Buffer.length; i++)
		{
			byte alaw = g711Buffer[i];
			alaw ^= 0xD5;
			
			int sign     =  alaw & 0x80;
			int exponent = (alaw & 0x70) >> 4;
			int value    = (alaw & 0x0F) >> 4 + 8;
			if (exponent != 0)
			{
				value += 0x0100;
			}
			if (exponent > 1)
			{
				value <<= (exponent - 1);
			}
			value = (char)((sign == 0 ? value : -value) & 0xFFFF);
			pcmBuffer[i*2+0] = (byte) (value      & 0xFF);
			pcmBuffer[i*2+1] = (byte) (value >> 8 & 0xFF);
		}
		return pcmBuffer;
	} 
    
    
}
